﻿using System;
using System.Collections.Generic;
using System.Data.Services.Client;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Text;
using LogService.DataAccessService;
using NLog;
using NLog.LogReceiverService;
using LogLevel = LogService.DataAccessService.LogLevel;

namespace LogService
{
    class LogReceiverService : ILogReceiverServer
    {
        private static readonly Uri DataAccessAddress = new Uri("http://localhost:3151/DataAccess.svc");
        private static SiteXtenderEntities AccessService = new SiteXtenderEntities(DataAccessAddress);

        public void ProcessLogMessages(NLogEvents nevents)
        {
            AccessService = new SiteXtenderEntities(DataAccessAddress);
            OperationContext context = OperationContext.Current;
            MessageProperties prop = context.IncomingMessageProperties;
            RemoteEndpointMessageProperty endpoint =
            prop[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;

            var events = nevents.ToEventInfo();
            foreach (LogEventInfo ev in events)
            {
                var logger = LogManager.GetLogger(ev.LoggerName);
                logger.Log(ev);

                var logLevel = new LogLevel() { Name = ev.Level.Name};
                var log = new Log()
                              {
                                  DateTime = ev.TimeStamp,
                                  LoggerName = ev.LoggerName,
                                  Message = ev.Message,
                              };
                object logGuid;
                if (ev.Properties.TryGetValue("Guid",out logGuid))
                    log.Guid = new Guid((string)logGuid);

                if (endpoint != null)
                    log.ClientAddress = String.Format("{0}:{1}", endpoint.Address, endpoint.Port);

                AccessService.AddToLogLevelSet(logLevel);
                AccessService.AddToLogSet(log);

                log.Level = logLevel;
                AccessService.SetLink(log, "Level", logLevel);

                try
                {
                    if (Program.ManagmentEndpoint != null && Program.ManagmentEndpoint.ClientEndpoint != null)
                        Program.ManagmentEndpoint.ClientEndpoint.SendLog(new ManagmentLog()
                        {
                            LoggerName = ev.LoggerName,
                            Level = ev.Level.Name,
                            Message = ev.Message,
                            TimeStamp = ev.TimeStamp,
                            Guid = log.Guid == null ? Guid.Empty : log.Guid.Value
                        });

                }
                catch (Exception)
                {
                    logger.Error("Sending log to silverlight client failed!");
                }
            }
            try { AccessService.SaveChanges(); }
            catch (DataServiceRequestException ex)
            { LogManager.GetCurrentClassLogger().Warn("Data service not working! "+ex.Message); }
        }
    }
}
